package com.easipass.framework.eirframeworkcoredsl;

import java.util.*;

public class ServiceNode extends LabelledServiceNode {
    private static final ArgumentNode[] NO_ARGUMENTS = new ArgumentNode[0];

    private List<TransitionNode> transitions;

    private Token token;

    private ArgumentNode[] arguments;

    private String appDefinitionName;

    ServiceNode(Token token,String appDefinitionName, ArgumentNode[] arguments, List<TransitionNode> transitions) {
        super(token.startPos,
                (transitions == null || transitions.isEmpty())
                        ? arguments == null || arguments.length == 0 ? token.endPos
                        : arguments[arguments.length - 1].endPos
                        : transitions.get(transitions.size() - 1).endPos);
        this.token = token;
        this.transitions = transitions;
        this.appDefinitionName = appDefinitionName;
        if (arguments != null) {
            this.arguments = Arrays.copyOf(arguments, arguments.length);
        } else {
            this.arguments = NO_ARGUMENTS;
        }
    }

    @Override
    public String toString() {
        return "Service: " + stringify(true);
    }

    @Override
    public String stringify(boolean includePositionalInfo) {
        StringBuilder s = new StringBuilder();
        if (hasLabel()) {
            s.append(getLabelString());
            s.append(":");
        }
        s.append(getName());
        if (arguments != null) {
            for (ArgumentNode argumentNode : arguments) {
                s.append(" --").append(argumentNode.getName()).append("=").append(argumentNode.getValue());
            }
        }
        if (includePositionalInfo) {
            s.append(":");
            s.append(getStartPos()).append(">").append(getEndPos());
        }
        for (int i = 0; i < transitions.size(); i++) {
            TransitionNode t = transitions.get(i);
            s.append(t.stringify(includePositionalInfo));
        }
        return s.toString();
    }

    @Override
    public void accept(Visitor visitor) {
        boolean cont = visitor.preVisit(this);
        if (!cont) {
            return;
        }
        visitor.visit(this);
        for (TransitionNode transition : transitions) {
            transition.accept(visitor);
        }
        visitor.postVisit(this);
    }

    public String getAppNamePrefix(String serviceName) {
        if (serviceName == null) {
            return "";
        } else {
            return serviceName + "-";
        }
    }

    public String toDslText() {
        StringBuilder s = new StringBuilder();
        if (getLabel() != null) {
            s.append(getLabelString()).append(": ");
        }
        s.append(token.stringValue());
        if (hasArguments()) {
            s.append(" ");
            for (ArgumentNode argumentNode : arguments) {
                s.append(" --").append(argumentNode.getName()).append("=").append(argumentNode.getValue());
            }
        }
        return s.toString();
    }

    @Override
    public boolean isServiceApp() {
        return true;
    }

    public List<TransitionNode> getTransitions() {
        return transitions;
    }

    public void setTransitions(List<TransitionNode> transitions) {
        this.transitions = transitions;
    }

    public boolean hasTransitions() {
        return transitions != null && !transitions.isEmpty();
    }


    public String getName() {
        return token.stringValue();
    }

    public boolean hasArguments() {
        return arguments != null && arguments.length != 0;
    }

    public ArgumentNode[] getArguments() {
        return arguments;
    }

    public Token getToken() {
        return token;
    }

    public String getExecutableDSLName() {
        StringBuilder s = new StringBuilder();
        if(appDefinitionName != null && !"".equals(appDefinitionName)){
            s.append(appDefinitionName)
            .append("-");
        }
        s.append(getLabel() == null ? getName() : getLabelString());
        return s.toString();
    }
}
